import { onMounted, reactive, ref } from "vue";
import type { BaseResource, ListResponse, MergePathReq } from "../k8s";
import type { BaseResponse } from "@/api/response";
import { type KRotuer, useVerifyRouter } from "@/router/use";

import { saveYamlAsFile } from "../../utils/file";
import { ElMessageBox } from "element-plus";
import { useI18n } from "vue-i18n";
import type { KubeRouteItem } from "../../router";

type ResourceCRUDReq<T extends BaseResource> = {
  getListReq?: (req: MergePathReq) => BaseResponse<ListResponse<T>>;
  getDetailsReq?: (req: MergePathReq, data?: T) => BaseResponse<T>;
  deleteReq?: (req: MergePathReq, data?: T) => BaseResponse;
  createReq?: (req: MergePathReq, data?: T) => BaseResponse;
  updateReq?: (req: MergePathReq, data?: T) => BaseResponse;
};

export const useBaseCRUDProvider = <T extends BaseResource>(
  arg: {
    request?: ResourceCRUDReq<T>;
  },
  autoReloadList: boolean = true
) => {
  const router = useVerifyRouter();
  const selections = ref<T[]>([]);
  const srcList = ref<T[]>([]);
  const uiState = reactive({
    loading: false
  });
  const { t } = useI18n();
  const query = reactive({
    cluster: "",
    namespace: "",
    paginationConfig: {
      currentPage: 1,
      pageSize: 10,
      total: 0
    },
    searchConfig: {
      keywords: ""
    }
  });

  onMounted(() => {
    const { cluster, namespace } = router.query;
    query.cluster = cluster;
    query.namespace = namespace;
    if (autoReloadList) {
      reloadResourceList();
    }
  });

  const reloadResourceList = async () => {
    selections.value = [];
    return getResourceList({
      cluster: query.cluster,
      namespace: query.namespace
    });
  };

  // 获取资源详情
  const getResourceDetails = async (
    req: MergePathReq,
    data: T
  ): Promise<BaseResponse<T>> => {
    return arg.request?.getDetailsReq?.(req, data);
  };

  const getResourceList = async (req: MergePathReq) => {
    selections.value = [];
    const res = await arg.request?.getListReq?.({
      ...req,
      namespace: req?.namespace
    });
    if (res && res.items) {
      srcList.value = res.items;
    }
  };

  const updateResource = async (
    req: MergePathReq,
    data: T
  ): Promise<BaseResponse> => {
    return arg.request?.updateReq?.(req, data);
  };

  const deleteResource = async (
    req: MergePathReq,
    data: T
  ): Promise<BaseResponse> => {
    return arg.request?.deleteReq?.(req, data);
  };

  const downloadSourceAsYaml = async (data: T, name?: string) => {
    const filename = name ?? `${data.metadata.name}.yaml`;

    getResourceDetails({}, data).then(res => {
      saveYamlAsFile(res, filename);
    });
  };

  const confirmDelete = async (data?: T) => {
    const targets = data ? [data] : selections.value;

    ElMessageBox.alert(
      `${t("commons.confirm_message.delete")}[${targets.map(item => item.metadata.name).join("、")}]`,
      t("commons.message_box.prompt")
    ).then(() => {
      Promise.all(targets.map(item => deleteResource({}, item))).then(() => {
        reloadResourceList();
      });
    });
  };

  return {
    selections,
    srcList,
    query,
    router,
    uiState,
    downloadSourceAsYaml,
    getResourceDetails,
    getResourceList,
    updateResource,
    deleteResource,
    confirmDelete,
    reloadResourceList
  };
};

export const useBaseCRUDRoute = (arg: {
  router: KRotuer;
  routeMap?: Record<string, KubeRouteItem>;
}) => {
  const pushTo = (name: string | KubeRouteItem, query?: any) => {
    let routeName = "";
    if (typeof name === "string") {
      if (arg.routeMap && arg.routeMap[name]) {
        routeName = arg.routeMap[name].name;
      } else {
        routeName = name;
      }
    } else if (name) {
      routeName = name.name;
    }
    console.log("try to push :", routeName, query);
    arg.router?.push({
      name: routeName,
      query
    });
  };

  const resolveUrl = (path: string | KubeRouteItem, query?: any) => {
    let routePath = "";
    if (typeof path === "string") {
      routePath = path;
    } else {
      routePath = path.path;
    }

    return arg.router?.router?.resolve({
      path: routePath,
      query
    });
  };

  const openBlank = (path: string | KubeRouteItem, query?: any) => {
    const url = resolveUrl(path, query);
    if (url?.href) {
      window.open(url?.href, "_blank");
    }
  };

  return { pushTo, resolveUrl, openBlank };
};
